/**
 * 数组类使用示例
 * 展示 zh-array.js 中 数组 类的各种功能
 */

// 导入数组类（根据环境支持动态导入）
const 数组 = require('../../zh/公共函数/zh-array.js').数组 || require('../../zh/公共函数/zh-array.js').default;

console.log('======= 数组类使用示例 =======\n');

// 1. 数组创建示例
console.log('1. 数组创建示例:');
const 空数组 = new 数组();
const 数字数组 = new 数组([1, 2, 3, 4, 5]);
const 字符串数组 = new 数组(['红', '绿', '蓝', '黄']);
const 单个元素数组 = new 数组('单个元素');
const 对象数组 = new 数组([{id: 1, name: '张三'}, {id: 2, name: '李四'}]);

console.log('空数组:');
空数组.打印();
console.log('数字数组:');
数字数组.打印();
console.log('字符串数组:');
字符串数组.打印();
console.log('单个元素数组:');
单个元素数组.打印();
console.log('对象数组:');
对象数组.打印();
console.log();

// 2. 基本属性和操作示例
console.log('2. 基本属性和操作示例:');
const 示例数组 = new 数组([10, 20, 30, 40, 50]);
console.log(`数组长度: ${示例数组.长度()}`);
console.log(`索引2的元素: ${示例数组.取(2)}`);
console.log(`原始数组值:`);
示例数组.打印();

// 获取原始数组
const 原始JS数组 = 示例数组.取值();
console.log(`获取的原始JS数组类型: ${Array.isArray(原始JS数组)}`);
console.log();

// 3. 数组元素增删改查示例
console.log('3. 数组元素增删改查示例:');
let 操作数组 = new 数组([1, 2, 3]);
console.log('初始数组:');
操作数组.打印();

// 添加元素
const 添加后数组 = 操作数组.添加(4, 5);
console.log('添加元素后:');
添加后数组.打印();
console.log('原数组保持不变:');
操作数组.打印(); // 原数组不变，展示不可变性

// 插入元素
const 插入后数组 = 操作数组.插入(1, 1.5, 1.75);
console.log('插入元素后:');
插入后数组.打印();

// 删除元素
const 删除后数组1 = 插入后数组.删除(1, 2);
console.log('删除元素后:');
删除后数组1.打印();

// 清空数组
const 空数组2 = 删除后数组1.清空();
console.log('清空后:');
空数组2.打印();
console.log();

// 4. 查找操作示例
console.log('4. 查找操作示例:');
const 查找数组 = new 数组([10, 20, 30, 40, 30, 50]);

// 查找元素
const 找到元素 = 查找数组.查找(item => item > 25);
console.log(`查找大于25的第一个元素: ${找到元素}`);

// 查找最后一个元素
const 找到最后元素 = 查找数组.查找最后(item => item > 25);
console.log(`查找大于25的最后一个元素: ${找到最后元素}`);

// 查找索引
const 找到索引 = 查找数组.查找索引(item => item === 30);
console.log(`查找值为30的第一个索引: ${找到索引}`);

// 查找最后索引
const 找到最后索引 = 查找数组.查找最后索引(item => item === 30);
console.log(`查找值为30的最后一个索引: ${找到最后索引}`);

// 判断包含
console.log(`是否包含40: ${查找数组.包含(40)}`);
console.log(`是否包含60: ${查找数组.包含(60)}`);

// 索引方法
console.log(`值为30的第一个索引: ${查找数组.索引(30)}`);
console.log(`值为30的最后一个索引: ${查找数组.最后索引(30)}`);
console.log();

// 5. 遍历和转换示例
console.log('5. 遍历和转换示例:');
const 转换数组 = new 数组([1, 2, 3, 4, 5]);

// 遍历
console.log('遍历数组:');
转换数组.遍历((item, index) => {
  console.log(`索引${index}: ${item}`);
});

// 映射
const 映射后数组 = 转换数组.映射(item => item * 2);
console.log('映射后(每个元素乘2):');
映射后数组.打印();

// 过滤
const 过滤后数组 = 转换数组.过滤(item => item % 2 === 0);
console.log('过滤后(偶数):');
过滤后数组.打印();

// 规约
const 总和 = 转换数组.规约((累加器, item) => 累加器 + item, 0);
console.log(`数组元素总和: ${总和}`);

// 全部满足
const 是否全部正数 = 转换数组.全部(item => item > 0);
console.log(`是否全部正数: ${是否全部正数}`);

// 部分满足
const 是否有偶数 = 转换数组.某些(item => item % 2 === 0);
console.log(`是否有偶数: ${是否有偶数}`);
console.log();

// 6. 数组排序和翻转示例
console.log('6. 数组排序和翻转示例:');
const 无序数组 = new 数组([3, 1, 4, 2, 5]);
console.log('原始无序数组:');
无序数组.打印();

// 默认排序
const 默认排序后 = 无序数组.排序();
console.log('默认排序后:');
默认排序后.打印();

// 自定义排序
const 降序排序后 = 无序数组.排序((a, b) => b - a);
console.log('降序排序后:');
降序排序后.打印();

// 对象数组排序
const 人员数组 = new 数组([
  {name: '张三', age: 30},
  {name: '李四', age: 25},
  {name: '王五', age: 35}
]);
const 按年龄排序 = 人员数组.排序((a, b) => a.age - b.age);
console.log('按年龄排序的人员:');
按年龄排序.打印();

// 翻转数组
const 翻转后 = 无序数组.翻转();
console.log('翻转后:');
翻转后.打印();
console.log();

// 7. 数组拼接和切片示例
console.log('7. 数组拼接和切片示例:');
const 数组A = new 数组([1, 2, 3]);
const 数组B = new 数组([4, 5, 6]);
const 普通数组 = [7, 8, 9];

// 拼接数组
const 拼接后 = 数组A.拼接(数组B, 普通数组, 10);
console.log('拼接多个数组后:');
拼接后.打印();

// 合并数组（与拼接功能相同）
const 合并后 = 数组A.合并(数组B);
console.log('合并两个数组后:');
合并后.打印();

// 切片
const 源数组 = new 数组([1, 2, 3, 4, 5, 6, 7]);
const 切片1 = 源数组.切片(2, 5);
const 切片2 = 源数组.切片(3);
const 切片3 = 源数组.切片(-3);

console.log('原始数组:');
源数组.打印();
console.log('从索引2到4的切片:');
切片1.打印();
console.log('从索引3到末尾的切片:');
切片2.打印();
console.log('最后3个元素的切片:');
切片3.打印();
console.log();

// 8. 数组填充和拷贝示例
console.log('8. 数组填充和拷贝示例:');
const 填充数组 = new 数组([1, 2, 3, 4, 5]);

// 填充
const 填充后1 = 填充数组.填充(0);
const 填充后2 = 填充数组.填充(9, 1, 4);

console.log('原始数组:');
填充数组.打印();
console.log('全部填充为0:');
填充后1.打印();
console.log('从索引1到3填充为9:');
填充后2.打印();

// 拷贝到
const 拷贝数组 = new 数组([1, 2, 3, 4, 5, 6, 7]);
const 拷贝后 = 拷贝数组.拷贝到(3, 0, 3);

console.log('拷贝后(将前3个元素拷贝到索引3处):');
拷贝后.打印();
console.log();

// 9. 数组拍平和高级操作示例
console.log('9. 数组拍平和高级操作示例:');

// 拍平
const 嵌套数组 = new 数组([1, [2, 3], [4, [5, 6]]]);
const 拍平1层 = 嵌套数组.拍平();
const 完全拍平 = 嵌套数组.拍平(2);

console.log('嵌套数组:');
嵌套数组.打印();
console.log('拍平1层:');
拍平1层.打印();
console.log('完全拍平:');
完全拍平.打印();

// 拍平映射
const 拍平映射数组 = new 数组([1, 2, 3]);
const 拍平映射结果 = 拍平映射数组.拍平映射(x => [x, x * 2]);
console.log('拍平映射结果:');
拍平映射结果.打印();

// 去重
const 重复数组 = new 数组([1, 2, 2, 3, 4, 4, 5]);
const 去重后 = 重复数组.去重();
console.log('去重前:');
重复数组.打印();
console.log('去重后:');
去重后.打印();

// 打乱
const 有序数组 = new 数组([1, 2, 3, 4, 5]);
const 打乱后 = 有序数组.打乱();
console.log('打乱后:');
打乱后.打印();
console.log();

// 10. 迭代器示例
console.log('10. 迭代器示例:');
const 迭代数组 = new 数组(['a', 'b', 'c', 'd']);

// 键迭代
console.log('键迭代:');
for (const 键 of 迭代数组.键迭代()) {
  console.log(`键: ${键}`);
}

// 值迭代
console.log('值迭代:');
for (const 值 of 迭代数组.值迭代()) {
  console.log(`值: ${值}`);
}

// 条目迭代
console.log('条目迭代:');
for (const [键, 值] of 迭代数组.条目迭代()) {
  console.log(`[${键}, ${值}]`);
}
console.log();

// 11. 字符串转换示例
console.log('11. 字符串转换示例:');
const 转换字符串数组 = new 数组([1, 2, 3, 4, 5]);

console.log(`默认分隔符拼接: ${转换字符串数组.按分隔符拼接()}`);
console.log(`自定义分隔符拼接: ${转换字符串数组.按分隔符拼接(' - ')}`);
console.log(`转字符串: ${转换字符串数组.转字符串()}`);
console.log(`转本地字符串: ${转换字符串数组.转本地字符串()}`);
console.log();

// 12. 静态方法示例
console.log('12. 静态方法示例:');

// 判断是否为数组
console.log(`是否为数组([1,2,3]): ${数组.是否数组([1,2,3])}`);
console.log(`是否为数组("abc"): ${数组.是否数组("abc")}`);
console.log(`是否为数组(new 数组([1,2,3])): ${数组.是否数组(new 数组([1,2,3]))}`);

// 从类数组创建
const 类数组 = {0: 'a', 1: 'b', 2: 'c', length: 3};
const 从类数组创建 = 数组.从(类数组);
console.log('从类数组创建:');
从类数组创建.打印();

// 从类数组创建并映射
const 从类数组映射 = 数组.从(类数组, x => x.toUpperCase());
console.log('从类数组创建并映射为大写:');
从类数组映射.打印();

// 创建指定长度数组
const 创建长度为5的数组 = 数组.创建(5, 0);
console.log('创建长度为5，填充0的数组:');
创建长度为5的数组.打印();

// 静态合并方法
const 静态合并 = 数组.合并([1, 2], new 数组([3, 4]), 5);
console.log('静态方法合并:');
静态合并.打印();
console.log();

// 13. 链式调用示例
console.log('13. 链式调用示例:');
const 链式数组 = new 数组([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

const 链式结果 = 链式数组
  .过滤(item => item % 2 === 1)     // 过滤出奇数
  .映射(item => item * 2)            // 乘以2
  .排序((a, b) => b - a)             // 降序排序
  .添加(22, 24)                       // 添加元素
  .切片(1, 4);                       // 取部分元素

console.log('链式调用结果:');
链式结果.打印();

// 14. 业务场景示例
console.log('14. 业务场景示例:');

// 场景1: 数组求和与平均值
function 数组统计(arr) {
  const 总和 = arr.规约((sum, item) => sum + item, 0);
  const 平均值 = 总和 / arr.长度();
  const 最大值 = arr.规约((max, item) => Math.max(max, item), arr.取(0));
  const 最小值 = arr.规约((min, item) => Math.min(min, item), arr.取(0));
  
  return { 总和, 平均值, 最大值, 最小值 };
}

const 成绩数组 = new 数组([85, 92, 78, 90, 88]);
const 统计结果 = 数组统计(成绩数组);
console.log('学生成绩统计:');
console.log(`总和: ${统计结果.总和}`);
console.log(`平均值: ${统计结果.平均值}`);
console.log(`最高分: ${统计结果.最大值}`);
console.log(`最低分: ${统计结果.最小值}`);

// 场景2: 数组分组
function 数组分组(arr, 分组函数) {
  const 分组结果 = {};
  
  arr.遍历(item => {
    const 键 = 分组函数(item);
    if (!分组结果[键]) {
      分组结果[键] = [];
    }
    分组结果[键].push(item);
  });
  
  // 转换为数组对象
  const 结果数组 = new 数组();
  for (const [键, 值] of Object.entries(分组结果)) {
    结果数组.添加({ 键, 值: new 数组(值) });
  }
  
  return 结果数组;
}

const 人员列表 = new 数组([
  {name: '张三', department: '技术部', age: 30},
  {name: '李四', department: '市场部', age: 25},
  {name: '王五', department: '技术部', age: 35},
  {name: '赵六', department: '市场部', age: 28},
  {name: '钱七', department: '财务部', age: 40}
]);

const 按部门分组 = 数组分组(人员列表, person => person.department);
console.log('按部门分组:');
按部门分组.遍历(group => {
  console.log(`${group.键}:`);
  group.值.遍历(p => console.log(`  ${p.name}, ${p.age}岁`));
});

// 场景3: 数组分页
function 数组分页(arr, 每页大小, 页码 = 1) {
  const 起始索引 = (页码 - 1) * 每页大小;
  const 结束索引 = 起始索引 + 每页大小;
  const 总页数 = Math.ceil(arr.长度() / 每页大小);
  
  return {
    数据: arr.切片(起始索引, 结束索引),
    总页数,
    当前页码: 页码,
    每页大小,
    总数量: arr.长度()
  };
}

const 大数组 = 数组.从({length: 25}, (_, i) => i + 1);
const 分页结果 = 数组分页(大数组, 10, 2);
console.log('分页结果:');
console.log(`第${分页结果.当前页码}页 (共${分页结果.总页数}页):`);
分页结果.数据.打印();
console.log();

console.log('======= 数组类使用示例结束 =======');